#include "Engine.h"

Engine::Engine(){
int i=0;
for(i=0;i<5;i++)Members.Layer[i]=new nRoomBuff;
for(i=0;i<3;i++)Members.Creatures[i]=new nEnemyList;
Members.RoomHeader=new RHeader; 
fp=NULL;


}

Engine::~Engine(){
int i=0;
for(i=0;i<5;i++) delete Members.Layer[i];
for(i=0;i<3;i++) delete Members.Creatures[i];
delete Members.RoomHeader; 

}
void Engine::CloseFile(){fclose(fp);}
void Engine::OpenFile(char *path){
fileloc=path;
OpenFile();
}
void Engine::OpenFile(){
 if(fp) fclose(fp);

 fp=fopen(fileloc,"r+b");
}
FILE* Engine::oFP(){return fp;}
void Engine::LoadHeader(long Offset){
	long blah=0;
	int BGi=0;
	OpenFile();
	fseek(fp,Offset,SEEK_SET);
	fread(&Members.RoomHeader->bTileset,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bBg0,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bBg1,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bBg2,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->lBg3,sizeof(u32),1,fp);
	fread(&Members.RoomHeader->lForeground,sizeof(u32),1,fp); 
	fread(&Members.RoomHeader->lLevelData,sizeof(u32),1,fp);
	fread(&Members.RoomHeader->lBackLayer,sizeof(u32),1,fp);
	fread(&Members.RoomHeader->lClipData,sizeof(u32),1,fp); 
	fread(&Members.RoomHeader->lBackgroundTSA,sizeof(u32),1,fp);
	fread(&Members.RoomHeader->bUnknown1,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->TransForeground,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->iSep1,sizeof(u16),1,fp);
	fread(&Members.RoomHeader->lSpritePointer,sizeof(u32),1,fp); 
	fread(&Members.RoomHeader->bSpriteIndex1,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bEventSwitch,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->iSep2,sizeof(u16),1,fp);
	fread(&Members.RoomHeader->lSpritePointer2,sizeof(u32),1,fp); 
	fread(&Members.RoomHeader->bSpriteIndex2,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bEventSwitch2,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->iSeperator,sizeof(u16),1,fp);
	fread(&Members.RoomHeader->lSpritePointer3,sizeof(u32),1,fp); 
	fread(&Members.RoomHeader->bSpriteIndex3,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bMiniMapRoomX,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bMiniMapRoomY,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bEffect,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bSceneryYPos,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bNothing,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->bMusic,sizeof(u8),1,fp);
	fread(&Members.RoomHeader->blank,sizeof(u8),1,fp);
	CloseFile();
//	SetSceneControls();
	
}
int Engine::LoadSpecialEffects(long EffectNum){

long  reference_table,tileset_table,ref_offset=0;
long  ani_source,gfx_destination,i,pointer=0;
 

u8 ref_array[0x30];
u8 Graphic[128];
 
 
/* Don't need these if statements for now.*/
/*if(file = "ZM" Then
 reference_table = &H35FA78
 tileset_table = &H35F948
 if (header = "PBMXP01") Then
    reference_table = &H360704
    tileset_table = &H3605D
 End if
Else
 reference_table = &H3C8F90
 tileset_table = &H3C8D58
End if*/
if(isZM()){
 reference_table = 0x35FA78;
 tileset_table = 0x35F948;
}else if(isMF()){
 reference_table = 0x3C8F90;
 tileset_table =0x3C8D58;
}
 ///if(!PreLoad){
OpenFile();

fseek(oFP(),reference_table + ((EffectNum&0xFF) * 0x30),SEEK_SET);
fread(&ref_array,sizeof(u8),0x30,oFP());

 for(i = 0; i < 16;i++){

	//if(    ref_array[i * 3] == 0) continue; 
	//if not last animation, but no animation there, exit)
	ani_source = (tileset_table + (8 * ref_array[i * 3]));
    fseek(oFP(),ani_source,SEEK_SET);
	fread(&SpecialEffects[i].Animated,sizeof(u8),1,oFP());
	fread(&SpecialEffects[i].Timer,sizeof(u8),1,oFP());
	fread(&SpecialEffects[i].GraphicEnd,sizeof(u16),1,oFP());
	fread(&SpecialEffects[i].GraphicPnt,sizeof(u32),1,oFP());
	gfx_destination = i *0x80; //if 0 is bufferstart...
	if(SpecialEffects[i].GraphicPnt<0x7FFFFFF) continue;
	fseek(oFP(),SpecialEffects[i].GraphicPnt - 0x8000000,SEEK_SET);

	fread(&Graphic[0],sizeof(u8),128,oFP());
	for (int ii = 0; ii < 128;ii++)	GameEngine->Members.fGbuf[gfx_destination + ii] = Graphic[ii];
 
 }
//Copy from Tilemem to BGMem

return 0;
}
int Engine::GetTileset(int Area, u8 Tileset){
	unsigned char decompbuf[84100]={0};
	long decomplength=0;
    //long Tileset=0;
	u16  TileCheck=0;
    int  i =0;
   memset(&Members.fGbuf,0,sizeof(Members.fGbuf));
   memset(&Members.BGBuf,0,sizeof(Members.BGBuf));
   memset(&Members.PcPalMem,0,sizeof( Members.PcPalMem));
    //Tileset = Combos[1].GetListIndex();
    OpenFile();
	
	fseek(fp,Members.RoomTilesets[Tileset].gTiles-0x8000000,SEEK_SET);//Seek the compressed Tileset
	fread(&CompBuffer,sizeof(char),64691,fp);//Read compression
	fseek(fp,Members.RoomTilesets[Tileset].pTiles-0x8000000,SEEK_SET);//Seek the endcoded pal
	fread(&GBAPal[32],sizeof(short),0x1E0,fp);//Read pal
	fseek(fp,Members.RoomTilesets[Tileset].TSAMap-0x8000000,SEEK_SET);

	
	memset(&Members.TSA.nTSA,0,sizeof(Members.TSA.nTSA));
	fread(&Members.TSA.ID,sizeof(short),1,fp); 
	Members.TSA.max=0;
	//fread(&TSA.nTSA,sizeof(short),0x1080,fp);
    for(i = 0;i<0x1080;i++){
          fread(&TileCheck,2,1,fp); 
		  	Members.TSA.nTSA[i]=TileCheck;
		  if(TileCheck==0x2){
		break;
		
		  }
		  	Members.TSA.max++;
	}
    Members.TSA.max/=4;

	GBAPal[0]=0;
	GBAPal[16] = 0;
	
	
	GetCRETileset(this,(unsigned char*)GBAPal,&Members.fGbuf[0], Area);

 

	   
    
	 
	long size =LZ77UnComp(CompBuffer, decompbuf);
		 
	//memcpy(fGbuf[6144],decompbuf[0],size);
   for( i = 0;i<size;i++)Members.fGbuf[6144+i]=decompbuf[i];
  
   LoadSpecialEffects(Members.RoomTilesets[Tileset].EffectSet);
   
  





	if(Members.RoomHeader->lBg3==0x40){
       fseek(fp,Members.RoomTilesets[Tileset].gBackground-0x8000000,SEEK_SET);//Seek the compressed Tileset
	fread(&CompBuffer,sizeof(char),32691,fp);//Read compression
   size = LZ77UnComp(CompBuffer, decompbuf);
	memcpy(&Members.BGBuf[0x7DE0-size],&decompbuf[0],size);
}
  for(int ii = 0; ii<512;ii++)  Members.BGBuf[0x7DE0+ii]=Members.fGbuf[0x600+ii];
	
DecodePal(GBAPal, Members.PcPalMem, 16, 0);



	return 0;

}